package com.training.schedule_management_system_admin.controller;

import com.alibaba.fastjson.JSONObject;
import com.training.schedule_management_system_admin.constant.Msg;
import com.training.schedule_management_system_admin.entity.User;
import com.training.schedule_management_system_admin.service.UserService;
import com.training.schedule_management_system_admin.utils.CodeUtils;
import com.training.schedule_management_system_admin.utils.EmailUtils;
import com.training.schedule_management_system_admin.utils.MD5Utils;
import com.training.schedule_management_system_admin.utils.UserUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import sun.security.provider.MD5;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;


@Controller
public class LoginController {

    @Autowired
    UserService userService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /*
    跳转到登录页面
     */
    @RequestMapping("/toLogin")
    public String login(Model model){
        return "/login";
    }

    /*
    跳转到修改密码页面
     */
    @RequestMapping("/reset-password")
    public String reset(Model model){

        return "/reset-password";
    }

    /*
    修改密码
     */
    @PostMapping("/resetPassword")
    public String resetPassword(Model model,String email,String code,String password,String confirmPassword){
        JSONObject jsonObject=new JSONObject();
        //判断验证码是否一致
        boolean flag = userService.checkCode(email,code);
        if(!flag){
            jsonObject.put("message","验证码不一致");
            model.addAttribute("failed",jsonObject);
            return "/reset-password";
        }
        if(!password.equals(confirmPassword)){
            jsonObject.put("message","两次输入的密码不一致");
            model.addAttribute("failed",jsonObject);
            return "/reset-password";
        }
        User user = userService.getUserByEmail(email);
        if(user==null){
            jsonObject.put("message","用户不存在");
            model.addAttribute("failed",jsonObject);
            return "/reset-password";
        }
        user.setPassword(MD5Utils.code(password));
        userService.reset(user);
        stringRedisTemplate.delete(email+"验证码:");
        jsonObject.put("message","修改成功!");
        model.addAttribute("success",jsonObject);
        return "/login";
    }

    /*
    拦截没有登录的请求
     */
    @RequestMapping("/noLogin")
    public String toLogin(Model model){
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("message","您还未登录，请先登录！");
//        return Msg.fail().add("failed",jsonObject);
        model.addAttribute("msg",jsonObject);
        model.addAttribute("user",new User());
        return "/login";
    }

    /*
    登录
     */
    @PostMapping("/loginAction")
    public String login(@RequestParam(value = "username",required = false)String username,
                        @RequestParam(value="password",required = false)String password,
                        Model model){
        JSONObject jsonObject=new JSONObject();
        //先判断该用户有无被限制登录
        Map<String, Object> map = userService.loginUserLock(username);
        if((boolean)map.get("flag")){//限制登录
            String msg="登录失败，因为用户"+username+"超过了限制密码错误次数，已被禁止登录！目前还剩余:"+map.get("lockTime")+"分钟";
            jsonObject.put("message",msg);
//            return Msg.fail().add("failed",jsonObject);
            model.addAttribute("msg",jsonObject);
            return "/login";
        }
        Subject subject= SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken(username, MD5Utils.code(password));
        try{
            subject.login(token);
        }catch (UnknownAccountException e){
            jsonObject.put("message","用户名不存在!");
//            return Msg.fail().add("failed",jsonObject);
            model.addAttribute("msg",jsonObject);
            return "/login";
        }catch (IncorrectCredentialsException e){
            //密码错误，相应操作
            String result = userService.loginValdate(username);
            jsonObject.put("message",result);
//            return Msg.fail().add("failed",jsonObject);
            model.addAttribute("msg",jsonObject);
            return "/login";
        }
        User user0 = userService.getUser(username, password);
        if(user0.getAuditState()==0){
            jsonObject.put("message","该用户还未审核完成，目前还不能登录!");
//            return Msg.fail().add("failed",jsonObject);
            model.addAttribute("msg",jsonObject);
            return "/login";
        }
        //登录成功，清除记录
        stringRedisTemplate.delete(UserUtils.getLoginFailCountKey(username));
        stringRedisTemplate.delete(UserUtils.getLoginTimeLockKey(username));
        User currentUser = userService.getUserWithRole(user0.getId());
        jsonObject.put("user",currentUser);
//        return Msg.success().add("success",jsonObject);
        model.addAttribute("msg",jsonObject);
        return "user/index";
    }

    /*
    退出
     */
    @RequestMapping("/logout")
    public String logout(Model model){
        JSONObject jsonObject=new JSONObject();
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        jsonObject.put("message","退出成功!");
//        return Msg.success().add("success",jsonObject);
        model.addAttribute("msg",jsonObject);
        return "/login";
    }

    /*
    没权限时返回信息
     */
    @RequestMapping("/noauth")
    public String unauthorized(Model model){
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("message","权限不足，无法访问!.");
//        return Msg.fail().add("failed",jsonObject);
        model.addAttribute("failed",jsonObject);
        return "/error/403";
    }

    /*
    先new一个User对象再跳转到注册页面
     */
    @RequestMapping("/toRegister")
    public String toRegister(Model model, HttpServletRequest request){
        HttpSession session = request.getSession();
        JSONObject jsonObject=new JSONObject();
        String result = stringRedisTemplate.opsForValue().get("是否开放注册");
        boolean flag=Boolean.parseBoolean(result);
        if(flag){
            jsonObject.put("message","当前为开放注册状态，注册成功后收到邮件即可登录.");
            model.addAttribute("user",new User());
            session.setAttribute("message",jsonObject);
            return "/register";
        }else{
            jsonObject.put("message","当前为关闭注册状态，注册成功后还需管理员审核后才能登录，管理员审核通过后会以邮件的方式通知您.");
            model.addAttribute("user",new User());
            session.setAttribute("message",jsonObject);
            return "/register";
        }
    }

    /*
    邮箱是否已被注册
     */
    @ResponseBody
    @RequestMapping("/email/{email}")
    public Msg email(@PathVariable String email){
        JSONObject jsonObject=new JSONObject();
        boolean u2=userService.checkUserByEmail(email);
        if(!u2){
            jsonObject.put("message","邮箱已被注册!");
            return Msg.fail().add("failed",jsonObject);
        }
        return Msg.success().add("success",jsonObject);
    }

    /*
    向该邮件发送验证码
     */
    @ResponseBody
    @RequestMapping("/email/sendCode/{email}")
    public Msg sendCode(@PathVariable String email){
        String code = CodeUtils.getCode();
        EmailUtils.sendCode(email,code);
        userService.setCode(email,code);
        return Msg.success();
    }

    /*
   注册
    */
    @PostMapping("/registerAction")
    public String register(/*@RequestBody*/ @ModelAttribute("user") User user,String confirmPassword,String code,Model model){
        JSONObject jsonObject=new JSONObject();
        //判断验证码是否一致
        boolean flag = userService.checkCode(user.getEmail(),code);
        if(!flag){
            jsonObject.put("message","验证码不一致");
//            return Msg.fail().add("failed",jsonObject);
            model.addAttribute("failed",jsonObject);
            return "/register";
        }
        if(!user.getPassword().equals(confirmPassword)){
            jsonObject.put("message","两次输入的密码不一致");
//            return Msg.fail().add("failed",jsonObject);
            model.addAttribute("failed",jsonObject);
            return "/register";
        }
        boolean u1=userService.checkUserByUsername(user.getUsername());
        if(!u1){
            jsonObject.put("message","用户名已存在!");
//            return Msg.fail().add("failed",jsonObject);
            model.addAttribute("failed",jsonObject);
            return "/register";
        }
        userService.saveUser(user);
        userService.saveRole(user.getId(),2);
        stringRedisTemplate.delete(user.getEmail()+"验证码:");
        jsonObject.put("message","注册成功!");
        jsonObject.put("user",user);
        EmailUtils.sendEmail(user);//发送邮件
//        return Msg.success().add("success",jsonObject);
        model.addAttribute("success",jsonObject);
        model.addAttribute("user",new User());
        return "/login";
    }
}
